
#include "GlutApplication.h"
#include "GlutWindow.h"

#include <glut.h>

// callback handlers
void GDisplayFunc()
{
    GlutApplication::instance()->onDisplay();
}

void GReshapeFunc(int w, int h)
{
    GlutApplication::instance()->onReshape(w, h);
}

void GVisibilityFunc(int state)
{
    GlutApplication::instance()->onVisibility(state);
}

void GKeyboardFunc(unsigned char key, int x, int y)
{
    GlutApplication::instance()->onKeyboard(key, x, y);
}

/// GlutApplication
GlutApplication* GlutApplication::pApp = 0;

GlutApplication::GlutApplication()
{
    init();
}

GlutApplication* GlutApplication::instance()
{
    if (!pApp)
        pApp = new GlutApplication;

    return pApp;
}

void GlutApplication::onDisplay()
{
    if (pActiveWindow)
        pActiveWindow->onDisplay();
}

void GlutApplication::onReshape(int w, int h)
{
    if (pActiveWindow) {
        pActiveWindow->nWidth = w;
        pActiveWindow->nHeight = h;
        pActiveWindow->onReshape(w, h);
    }
}

void GlutApplication::onVisibility(int state)
{
    if (pActiveWindow)
        pActiveWindow->onVisibility(state);
}

void GlutApplication::onKeyboard(unsigned char key, int x, int y)
{
    if (pActiveWindow)
        pActiveWindow->onKeyboard(key, x, y);
}

void GlutApplication::init()
{
    int argc = 1;
    char* argv[] = {"test"};
    pActiveWindow = 0;

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutDisplayFunc(GDisplayFunc);
    glutReshapeFunc(GReshapeFunc);
    glutVisibilityFunc(GVisibilityFunc);
    glutKeyboardFunc(GKeyboardFunc);
    glClearColor(0, 0, 0, 0);
}

int GlutApplication::exec()
{
    glutMainLoop();
    return 0;
}

void GlutApplication::setActiveWindow(AbstractGlutWindow* pWindow)
{
    pActiveWindow = pWindow;
}

AbstractGlutWindow* GlutApplication::activeWindow()
{
    return pActiveWindow;
}




